package cate.game.role.farm.tower;

import cate.common.table.d.*;
import cate.common.table.farm.tower.row.TowerMainRow;
import cate.common.table.farm.tower.row.TowerRewardRow;
import cate.common.util.GameResult;
import cate.game.play.part.FightSide;
import cate.game.play.proce.play.PlayPO;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.role.Role;
import cate.game.role.farm.AbstractFarm;
import cate.game.role.farm.PlayTimes;
import cate.game.role.farm.tower.msg.TowerDataResp;
import cate.game.role.farm.tower.msg.TowerRewardResp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.HashMap;
import java.util.Map;

@NoteClass(value = "美食神殿")
public class Tower extends AbstractFarm {
    @NoteField(value = "已通过的层数")
    public int passedFloor;

    @NoteField(value = "已领取普通奖励的记录", detail = "Map<tid, 是否已领取>")
    public Map<Integer, Boolean> rewardGot;

    @NoteField(value = "扫荡次数")
    public PlayTimes mopTimes;

    @NoteField(value = "今日已经挑战的次数")
    public int todayPassed;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (rewardGot == null) {
            rewardGot = new HashMap<>();
        }
        if (mopTimes == null) {
            mopTimes = new PlayTimes();
        }
        mopTimes.initialize();
    }

    public EcResult<Void> challenge(int floor, boolean mop){
        EcResult<Void> r = new EcResult<>();
        if(!isOpen()){
            return r.fail("缚灵之塔未开启");
        }
        if(isFighting()){
            return r.fail("正在挑战中");
        }
        int canFloor = mop ? this.passedFloor : (this.passedFloor + 1);
        if (floor > canFloor || (!mop && floor != canFloor)) {
            return r.fail(String.format("请先挑战第%d层", canFloor));
        }
        if (!mop) {
            r = doChallenge(floor);
            if (!r.ok()) {
                return r;
            }
        } else {
            GameResult<Void> ableRes = mopTimes.available(role, getFuncId());
            if (!ableRes.ok()) {
                return ableRes;
            }
            r = mopChallenge(floor);
            if (!r.ok()) {
                return r;
            }
            mopTimes.added();
            role.getHistory().action.mainTowenWinTimes();
        }
        noticeUpdate();
        role.getHistory().action.challengeMainTower();
        return r.success();
    }

    protected GameResult<Void> mopChallenge(int floor) {
        GameResult<Void> r = new GameResult<>();
        TowerMainRow tpl = role.getGame().table.tower.main.get(floor);
        if(tpl == null){
            return r.fail("配置异常");
        }
        MixRes reward = new MixRes(tpl.rewardStr);
        reward.add(role, true, GDOperation.TOWER_CHALLENGE);
        role.getGame().notice.dialogReward(role, reward);
        return r;
    }

    private GameResult<Void> doChallenge(int floor) {
        GameResult<Void> r = new GameResult<>();
        TowerMainRow tpl = role.getGame().table.tower.main.get(floor);
        if(tpl == null){
            return r.fail("配置异常");
        }
        // 挑战模式
        EcResult<FightSide> fsr = role.getGame().fight.side.createFightSideByCode(GDFight.Team.B, tpl.dynInsCode);
        if(!fsr.ok()){
            return r.fail(fsr.message);
        }
        TowerFTC context = new TowerFTC(role, tpl);
        context.playStory.level = floor;
        context.setPositionApply(GDFunc.ADVENTURE);
        // 自动扫荡不发录像 后台倍速播放
        EcResult<PlayPO> fightRes = role.getGame().play.startByRole(role, context, fsr.data);
        if (!fightRes.ok()) {
            return r.fail(fightRes.message);
        }
        startFighting();
        return r;
    }

    @JsonIgnore
    public GameResult<Void> getReward(int tid){
        GameResult<Void> r = new GameResult<>();
        TowerRewardRow rewardRow = role.getGame().table.tower.reward.get(tid);
        if(rewardRow == null){
            return r.fail("错误的奖励");
        }
        if(!isOpen()){
            return r.fail("该神殿未开启");
        }
        Boolean got = rewardGot.get(rewardRow.id);
        if (got != null && got) {
            return r.fail("奖励已领取");
        }
        if (rewardRow.floor > passedFloor) {
            return r.fail("尚未通过这一层，怎能领取奖励呢？一定用了外挂吧？");
        }
        rewardGot.put(rewardRow.id, true);
        new MixResAdder()
                .setOperation(GDOperation.TOWER_REWARD)
                .setOperationSub(tid)
                .setSendMailWhenFull(true)
                .setRes(rewardRow.rewardStr)
                .setDialogReward(true)
                .exe(role);
        role.sendNow(new TowerRewardResp(tid));
        return r.success();
    }

    public void noticeUpdate(){
        if(isOpen()){
            role.sendNow(new TowerDataResp(this));
        }
    }

    @Override
    public void onDaySpan(boolean silence){
        role.getRes().findBack.triggerByFuncId(getFuncId());
        mopTimes.reset();
        todayPassed = 0;
        if(!silence){
            noticeUpdate();
        }
    }

    /**
     * 只能gm使用
     */
    public GameResult<Void> gmClearTowerData(){
        GameResult<Void> r = new GameResult<>();
        mopTimes.reset();
        todayPassed = 0;
        noticeUpdate();
        return r;
    }

    @Override
    public int getFuncId() {
        return GDFunc.TOWER;
    }

    @Override
    public void onAfterOpen() {
        noticeUpdate();
    }

    @Override
    public int getFightFuncId() {
        return GDFunc.TOWER;
    }
}
